package com.moshme.web.controller.project;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.moshme.common.core.controller.BaseController;
import com.moshme.common.core.domain.AjaxResult;
import com.moshme.common.exception.ServiceException;
import com.moshme.common.utils.file.FileUtils;
import com.moshme.project.domain.File;
import com.moshme.project.domain.FileExample;
import com.moshme.project.domain.FileProject;
import com.moshme.project.domain.vo.FileBase64;
import com.moshme.project.service.FileExampleService;
import com.moshme.project.service.FileProjectService;
import com.moshme.project.service.FileService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Kieyfr
 * @version 1.0
 * @description 文件中心控制器
 * @date 2023/8/21 15:43
 */
@RestController
@RequestMapping("file")
public class FileController extends BaseController {

    @Autowired
    private FileService fileService;

    @Autowired
    private FileExampleService fileExampleService;

    @Autowired
    private FileProjectService fileProjectService;

    /**
     * 获取范例文件夹内的文件
     *
     * @param path
     * @return
     */
    @GetMapping("/fileList")
    @ApiOperation(value = "获取范例文件夹内的文件")
    public AjaxResult getFileList(String path) {
        LambdaQueryWrapper<FileExample> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        FileExample fileExample = fileExampleService.getOne(lambdaQueryWrapper.eq(FileExample::getFileTreePath, path));
        List<String> fileList = new ArrayList<>();
        if (fileExample != null) {
            fileList = fileExample.getFileList();
        }
        return success(fileList);
    }

    /**
     * 模糊获取范例多层图片
     *
     * @param path
     * @param path
     * @return
     */
    @GetMapping("/template/fileList")
    @ApiOperation(value = "模糊获取范例多层图片")
    public AjaxResult getTemplateFileList(String path) {
        LambdaQueryWrapper<FileExample> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<FileExample> list = fileExampleService.list(lambdaQueryWrapper.like(FileExample::getFileTreePath, path));
        return success(list);
    }

    /**
     * 范例上传文件
     *
     * @param file
     * @param path
     * @return
     */
    @PostMapping("/template/upload")
    @ApiOperation(value = "范例上传文件")
    public AjaxResult templateUpload(MultipartFile file, String path){
        List<String> fileList = fileService.templateUpload(file, path);
        return success(fileList);
    }

    /**
     * 范例删除文件
     *
     * @param path
     * @return
     */
    @GetMapping("/template/delete")
    @ApiOperation(value = "范例删除文件")
    public AjaxResult templateDelete(String path) {
        if (!fileService.templateDelete(path)) {
            return error("删除失败");
        }
        return success("删除成功");
    }

    /**
     * 获取项目文件夹内的文件
     *
     * @param path
     * @param projectId
     * @param id
     * @return
     */
    @GetMapping("/project/fileList")
    @ApiOperation(value = "获取项目文件夹内的文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "path", value = "存储地址"),
            @ApiImplicitParam(name = "projectId", value = "项目id"),
            @ApiImplicitParam(name = "id", value = "模块id，如(燃气主控阀id)"),
    })
    public AjaxResult getProjectFileList(String path, Long projectId, Long id) {
        List<String> strings = Arrays.stream(path.split("/")).collect(Collectors.toList());
        strings.add(1, id.toString());
        path = "项目/" + projectId + "/" + String.join("/", strings);
        LambdaQueryWrapper<FileProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        FileProject fileProject = fileProjectService.getOne(lambdaQueryWrapper.eq(FileProject::getFileTreePath, path).eq(FileProject::getProjectId, projectId));
        List<String> fileList = new ArrayList<>();
        if (fileProject != null) {
            fileList = fileProject.getFileList();
        }
        return success(fileList);
    }

    /**
     * 模糊获取项目多层图片
     *
     * @param path
     * @param path
     * @return
     */
    @GetMapping("/project/fileLists")
    @ApiOperation(value = "模糊获取项目多层图片")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "path", value = "存储地址"),
            @ApiImplicitParam(name = "projectId", value = "项目id"),
            @ApiImplicitParam(name = "id", value = "模块id，如(燃气主控阀id),如果需要获取模板级则必须填写"),
    })
    public AjaxResult getProjectFileLists(String path, Long projectId, Long id) {
        if (id != null) {
            List<String> strings = Arrays.stream(path.split("/")).collect(Collectors.toList());
            strings.add(1, id.toString());
            path = "项目/" + projectId + "/" + String.join("/", strings);
        } else if (path == null) {
            path = "项目/" + projectId + "/";
        } else {
            path = "项目/" + projectId + "/" + path;
        }
        LambdaQueryWrapper<FileProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<FileProject> list = fileProjectService.list(lambdaQueryWrapper.like(FileProject::getFileTreePath, path).eq(FileProject::getProjectId, projectId));
        return success(list);
    }

    /**
     * 项目上传文件
     *
     * @param file
     * @param path
     * @param projectId
     * @param id
     * @param longitude
     * @param latitude
     * @return
     * @throws IOException
     */
    @PostMapping("/project/upload")
    @ApiOperation(value = "项目上传文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件流"),
            @ApiImplicitParam(name = "path", value = "存储地址"),
            @ApiImplicitParam(name = "projectId", value = "项目id"),
            @ApiImplicitParam(name = "id", value = "模块id，如(燃气主控阀id)"),
            @ApiImplicitParam(name = "longitude", value = "经度"),
            @ApiImplicitParam(name = "latitude", value = "纬度")
    })
    public AjaxResult projectUpload(MultipartFile file, String path, Long projectId, Long id,
                                    @RequestParam(defaultValue = "", value = "longitude") String longitude,
                                    @RequestParam(defaultValue = "", value = "latitude") String latitude){
        List<String> strings = Arrays.stream(path.split("/")).collect(Collectors.toList());
        strings.add(1, id.toString());
        path = "项目/" + projectId + "/" + String.join("/", strings);
        List<String> fileList = fileService.projectUpload(file, path, projectId, longitude, latitude);
        return success(fileList);
    }

    /**
     * 项目删除文件
     *
     * @param path
     * @return
     */
    @DeleteMapping("/project/delete")
    @ApiOperation(value = "项目删除文件")
    public AjaxResult deleteProject(String path, Long projectId) {
        if (!fileService.projectDelete(path, projectId)) {
            return error("删除失败");
        }
        return success("删除成功");
    }

    /**
     * 获取文件流(Base64编码)
     *
     * @param path
     * @return
     */
    @GetMapping("/download/base64")
    @ApiOperation(value = "获取文件流(Base64编码)")
    public AjaxResult downloadBase64(String path) {
        LambdaQueryWrapper<File> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        File file = fileService.getOne(lambdaQueryWrapper.eq(File::getNetworkPath, path));
        String str = "";
        try {
            str = "data:image/png;base64," + FileUtils.readBase64File(file.getLocalPath());
        } catch (IOException e) {
            throw new ServiceException("图片获取失败");
        }
        return success((Object) str);
    }

    /**
     * 获取多个文件流(Base64编码)
     *
     * @param paths
     * @return
     */
    @PostMapping("/downloads/base64")
    @ApiOperation(value = "获取多个文件流(Base64编码)")
    public AjaxResult downloadsBase64(@RequestBody List<String> paths) {
        LambdaQueryWrapper<File> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<File> files = fileService.list(lambdaQueryWrapper.in(File::getNetworkPath, paths));
        List<FileBase64> list = new ArrayList<>();
        try {
            for (File file : files) {
                FileBase64 base64 = new FileBase64();
                base64.setBase64("data:image/png;base64," + FileUtils.readBase64File(file.getLocalPath()));
                base64.setPath(file.getNetworkPath());
                list.add(base64);
            }

        } catch (IOException e) {
            throw new ServiceException("图片获取失败");
        }
        return success(list);
    }

    /**
     * 获取文件流
     *
     * @param path
     * @return
     */
    @GetMapping("/download")
    @ApiOperation(value = "获取文件流")
    public void download(String path, HttpServletResponse response) {
        LambdaQueryWrapper<File> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        File file = fileService.getOne(lambdaQueryWrapper.eq(File::getNetworkPath, path));
        try {
            byte[] fileData = FileUtils.readFile(file.getLocalPath());
            // 设置响应头信息
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
            // 将图片流写入响应输出流
            response.getOutputStream().write(fileData);
            response.getOutputStream().flush();
        } catch (IOException e) {
            throw new ServiceException("文件获取失败");
        }
    }


}
